-- spleefgen.lua
-- vim:se fdm=marker:
------------------------------------------------------------------------------
-- Title: Spleef Block generate
-- Authors: Jack Zackowitz, Jeremy Wolff, Robert Plante
-- Description: generates the spleef map
------------------------------------------------------------------------------

------------------------------------------------------------------------------
-- helpers
------------------------------------------------------------------------------
-- is elem in tbl?
function is_in_table(elem, tbl)
  for i,v in ipairs(tbl) do
    if elem == v then
      return true
    end
  end
  return false
end

-- removes a numerically indexed element from a table, given its value
function remove_element(tbl, elem)
  local key = -1
  for i = 1, table.maxn(tbl) do
    if elem == tbl[i] then
      key = i
    end
  end

  if key > -1 then
    table.remove(tbl, key)
  end
end

-- returns rx, ry, rz for the given angle in degrees.
-- not perfect but works okay I guess
-- Best we have, not much else can bedone
function get_rotation(angle)
  -- normalize the angle
  while angle > 360 do
    angle = angle - 360
  end

  -- make the angle negative, kaneva seems to like this
  angle = -angle

  -- convert angle to radians
  rad = (angle*math.pi)/180

  -- get components of rotation
  rx = math.sin(rad)
  ry = 0
  rz = math.cos(rad)

  return rx, ry, rz
end

------------------------------------------------------------------------------
-- Chris' levels
------------------------------------------------------------------------------
FLATS = 1
CENTRAL_CORE = 2
CROSSROADS = 3
NARROW_STRAIGHTS = 4

-- {{{1
-- NOTE: each spawn point should look like this:
-- {block_x, block_y, rot}
-- (block x and z should be table indexes, not game space coordinates)
-- (rot should be an angle in degrees)
-- allowed.
spawn_points = {
  -- flats
  {
    {2, 2, 135}, -- player one
    {2, 9, 45},  -- player two
    {9, 9, -45}, -- player three
    {9, 2, -135} -- player four
  },
  -- central core
  {
    {7,4, -135}, 
    {4,7,  45 }, 
    {7,10,-45 },
    {10,7,-135},
  },
  -- crossroads
  {
    {10,10,-135},
    {11,10, 45 },
    {10,11,-45 },
    {11,11,-135},
  },
  -- narrow straights
  {
    {15,15,-90},-- player one
    {17,15,45}, -- player two
    {15,19,-45},-- player three
    {17,19,-135},-- player four
    {8,9  , 90}, -- player five
    {24,9 , 90}, -- player six
    {8,25 , 90}, -- player seven
    {24,25, 90}, -- player eight
  }
}

levels = {
  -- flats
  {
    {1,1,1,1,1,1,1,1,1,1},
    {1,2,2,2,2,2,2,2,2,1},
    {1,2,2,2,2,2,2,2,2,1},
    {1,2,2,2,2,2,2,2,2,1},
    {1,2,2,2,2,2,2,2,2,1},
    {1,2,2,2,2,2,2,2,2,1},
    {1,2,2,2,2,2,2,2,2,1},
    {1,2,2,2,2,2,2,2,2,1},
    {1,2,2,2,2,2,2,2,2,1},
    {1,1,1,1,1,1,1,1,1,1},
  },

  -- central core
  {
    {1,1,1,1,1,1,1,1,1,1,1,1,1},
    {1,1,2,2,2,2,2,2,2,2,2,1,1},
    {1,2,2,1,2,2,2,2,2,1,2,2,1},
    {1,2,1,1,1,2,2,2,1,1,1,2,1},
    {1,2,2,1,2,2,2,2,2,1,2,2,1},
    {1,2,2,2,2,2,2,2,2,2,2,2,1},
    {1,2,2,2,2,2,1,2,2,2,2,2,1},
    {1,2,2,2,2,2,2,2,2,2,2,2,1},
    {1,2,2,1,2,2,2,2,2,1,2,2,1},
    {1,2,1,1,1,2,2,2,1,1,1,2,1},
    {1,2,2,1,2,2,2,2,2,1,2,2,1},
    {1,1,2,2,2,2,2,2,2,2,2,1,1},
    {1,1,1,1,1,1,1,1,1,1,1,1,1},
  },

  -- crossroads
  {
    {1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1},
    {1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1},
    {1,1,1,2,2,2,2,0,0,0,0,0,0,2,2,2,2,1,1,1},
    {1,1,2,2,2,2,0,0,0,0,0,0,0,0,2,2,2,2,1,1},
    {1,2,2,2,2,2,2,1,1,1,1,1,1,2,2,2,2,2,2,1},
    {2,2,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,2},
    {2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2},
    {2,2,0,0,1,2,2,2,2,2,2,2,2,2,2,1,0,0,2,2},
    {2,2,0,0,1,2,2,2,2,2,2,2,2,2,2,1,0,0,2,2},
    {2,2,0,0,1,1,2,2,2,2,2,2,2,2,1,1,0,0,2,2},
    {2,2,0,0,1,1,2,2,2,2,2,2,2,2,1,1,0,0,2,2},
    {2,2,0,0,1,2,2,2,2,2,2,2,2,2,2,1,0,0,2,2},
    {2,2,0,0,1,2,2,2,2,2,2,2,2,2,2,1,0,0,2,2},
    {2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2},
    {2,2,2,2,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,2},
    {1,2,2,2,2,2,2,1,1,1,1,1,1,2,2,2,2,2,2,1},
    {1,1,2,2,2,2,0,0,0,0,0,0,0,0,2,2,2,2,1,1},
    {1,1,1,2,2,2,2,0,0,0,0,0,0,2,2,2,2,1,1,1},
    {1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1},
    {1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1},
  },

  -- narrow straights
  {
    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0},
    {1,0,0,2,2,2,2,2,2,0,1,1,1,1,1,1,1,1,1,1,1,0,2,2,2,2,2,2,0,0,1,0,0},
    {1,0,0,2,2,2,2,2,2,0,1,1,1,1,1,1,1,1,1,1,1,0,2,2,2,2,2,2,0,0,1,0,0},
    {1,0,0,2,2,0,0,2,2,0,1,1,1,1,1,1,1,1,1,1,1,0,2,2,0,0,2,2,0,0,1,0,0},
    {1,0,0,2,2,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,0,2,2,0,0,1,0,0},
    {1,0,0,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,1,0,0},
    {1,0,0,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,1,0,0},
    {1,0,0,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,1,0,0},
    {1,0,0,2,2,0,0,2,2,0,0,0,0,0,2,2,2,0,0,0,0,0,2,2,0,0,2,2,0,0,1,0,0},
    {1,0,0,2,2,0,0,2,2,0,1,1,1,0,2,2,2,0,1,1,1,0,2,2,0,0,2,2,0,0,1,0,0},
    {1,0,0,2,2,2,2,2,2,0,1,1,1,0,2,2,2,0,1,1,1,0,2,2,2,2,2,2,0,0,1,0,0},
    {1,0,0,2,2,2,2,2,2,0,1,1,1,0,2,2,2,0,1,1,1,0,2,2,2,2,2,2,0,0,1,0,0},
    {1,0,0,0,0,2,2,0,0,0,1,1,1,0,2,2,2,0,1,1,1,0,0,0,2,2,0,0,0,0,1,0,0},
    {1,0,0,1,0,2,2,0,1,1,1,1,1,0,2,2,2,0,1,1,1,1,1,0,2,2,0,1,0,0,1,0,0},
    {1,0,0,1,0,2,2,0,1,1,1,1,1,0,2,2,2,0,1,1,1,1,1,0,2,2,0,1,0,0,1,0,0},
    {1,0,0,1,0,2,2,0,1,1,1,1,1,0,2,2,2,0,1,1,1,1,1,0,2,2,0,1,0,0,1,0,0},
    {1,0,0,0,0,2,2,0,0,0,1,1,1,0,2,2,2,0,1,1,1,0,0,0,2,2,0,0,0,0,1,0,0},
    {1,0,0,2,2,2,2,2,2,0,1,1,1,0,2,2,2,0,1,1,1,0,2,2,2,2,2,2,0,0,1,0,0},
    {1,0,0,2,2,2,2,2,2,0,1,1,1,0,2,2,2,0,1,1,1,0,2,2,2,2,2,2,0,0,1,0,0},
    {1,0,0,2,2,0,0,2,2,0,1,1,1,0,2,2,2,0,1,1,1,0,2,2,0,0,2,2,0,0,1,0,0},
    {1,0,0,2,2,0,0,2,2,0,1,1,1,0,2,2,2,0,1,1,1,0,2,2,0,0,2,2,0,0,1,0,0},
    {1,0,0,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,1,0,0},
    {1,0,0,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,1,0,0},
    {1,0,0,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,1,0,0},
    {1,0,0,2,2,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,0,2,2,0,0,1,0,0},
    {1,0,0,2,2,0,0,2,2,0,1,1,1,1,1,1,1,1,1,1,1,0,2,2,0,0,2,2,0,0,1,0,0},
    {1,0,0,2,2,2,2,2,2,0,1,1,1,1,1,1,1,1,1,1,1,0,2,2,2,2,2,2,0,0,1,0,0},
    {1,0,0,2,2,2,2,2,2,0,1,1,1,1,1,1,1,1,1,1,1,0,2,2,2,2,2,2,0,0,1,0,0},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0},
    {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0},
    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0},
  }
}

block_scripts = {
  "SpleefBlockFlats.lua",
  "SpleefBlockCentralCore.lua",
  "SpleefBlockCrossroads.lua",
  "SpleefBlockNarrowStraights.lua"
}
-- }}}1

------------------------------------------------------------------------------
-- constants (you can edit these)
------------------------------------------------------------------------------
-- the level that this zone will use (an index in the levels table in
-- levels.lua)
LEVEL_NUMBER = nil
LEVEL = nil
-- global id of the spleef block object
SPLEEF_BLOCK_GLID = 1065
-- global id of the solid block object
WALL_GLID = 3637185
-- the script to be attached to sleef blocks
-- NOTE: need to upload this to the server via Upload Script before it can
-- be used.
SPLEEF_BLOCK_SCRIPT = "SpleefBlock.lua"
-- the texture to be applied to spleef blocks
--SPLEEF_BLOCK_TEXTURE = "filestore9/5224732/6645370/SpiffBlock.jpg"
-- the texture to be applied to solid blocks
--WALL_TEXTURE = "filestore9/5224732/6645370/SpiffBlock.jpg"
-- the {x, y, z} coordinates of the game lobby
LOBBY = {48.0, 0.0, -4.0}
-- size of spleef arena (in blocks)
WIDTH = 0
HEIGHT = 0
-- size of a spleef block (they're cubes, so are the same size in all
-- dimensions)
BLOCK_SIZE = 8
-- location of arena
ARENA_X, ARENA_Y, ARENA_Z = 0, 30, 0
-- minimum number of players that are needed for a game (set to 1 for testing)
MIN_PLAYERS = 1
-- maximum number of players that can play at once
MAX_PLAYERS = 1

------------------------------------------------------------------------------
-- initialization 
------------------------------------------------------------------------------
-- should call this before anything else
function set_level(n)
  LEVEL_NUMBER = n
  LEVEL = levels[LEVEL_NUMBER]
  SPLEEF_BLOCK_SCRIPT = block_scripts[LEVEL_NUMBER]
  MAX_PLAYERS = table.getn(spawn_points[LEVEL_NUMBER])
  WIDTH = table.getn(LEVEL)
  HEIGHT = table.getn(LEVEL[1])
end

------------------------------------------------------------------------------
-- player data code
------------------------------------------------------------------------------
WINS = "wins"
LOSSES = "losses"
ENEMIES_DEFEATED = "kills"

function tally_loss(user)
  if not user then return end
  local pn = kgp.playergetname(user)
  local losses = kgp.playerloaddata(pn, 1, LOSSES)
  if not losses then losses = 0 end
  losses = tonumber(losses) + 1
  kgp.playersavedata(pn, 1, LOSSES, tostring(losses))
end

function tally_win(user, enemies_defeated)
  if not user then return end
  local pn = kgp.playergetname(user)
  local wins = kgp.playerloaddata(pn, 1, WINS)
  local kills = kgp.playerloaddata(pn, 1, ENEMIES_DEFEATED)
  if not wins then wins = 0 end
  if not kills then kills = 0 end
  if not enemies_defeated then enemies_defeated = 0 end
    wins = tonumber(wins) + 1
    kills = tonumber(kills) + enemies_defeated
    kgp.playersavedata(pn, 1, WINS, tostring(wins))
    kgp.playersavedata(pn, 1, ENEMIES_DEFEATED, tostring(enemies_defeated))
end

--[[
local ranks = {
  {"DASH BREAK CADET", 0},
}
--]]

function print_score(user)
  if not user then return end
  local pn = kgp.playergetname(user)
  local wins = kgp.playerloaddata(pn, 1, WINS)
  local losses = kgp.playerloaddata(pn, 1, LOSSES)
  local kills = kgp.playerloaddata(pn, 1, ENEMIES_DEFEATED)
  if not wins then wins = 0 end
  if not losses then losses = 0 end
  if not kills then kills = 0 end
  local dbar = ((tonumber(kills) + 1 * tonumber(wins + 1))/tonumber(losses + 1)) * 10
  say("Player " .. pn .. "'s record: " .. wins .. " wins / "
    .. losses .. " losses. DBAR: " .. dbar)
end

------------------------------------------------------------------------------
-- player mgmt code
------------------------------------------------------------------------------
ready_to_spawn = false
gearing_up_timer = 0
-- have the players begun to teleport?
gearing_up = false
gearing_up_timer = 0
lasttick = 0
display = false
display_timer = 0
oldtick = 0
-- is the game running? this should happen two seconds after gearing up
running = false
-- list of player's who are ready to go
ready = {}
-- list of player's who aren't ready to go
notready = {}
-- how many players have been queried, how many need to be,
-- and how long they have
asking = false
asked = 0
toask = 0
timetoask = 0
-- list of player ID's that are currently in the game. only indexes
-- 1 to MAX_PLAYERS will be in a game at the given time, the rest will be in
-- the queue
players = {}
-- number of players in game
num_players = MIN_PLAYERS
-- add a player here when they've lost (first added is in last place, 
-- last added is winner)
rankings = {}

-- my current id (changes each session, as far as i can tell). add yours
-- here for debugging
--players = {}

-- the first player to lose has to leave the game. the next person lined up
-- in the queue will get to play.
loser = 0

-- This is the message string that will be output whenever there is a game
-- going on, it just stacks up
gamestatus = "Game stats and information."

-- Update the player menus by showing where the player is in the list
-- and what the list looks like up to 8, then the length of the list
function updatemenus()
	local tablelength = # players
	for i = 1, tablelength do
		local message = "" .. kgp.playergetname(players[i]) ..", your position in the queue is:\n" .. i .. ". " .. kgp.playergetname(players[i]) .. "\n\nThe current queue is:"
		for j = 1,tablelength do
			message = message .. "\n" .. j .. ". " .. kgp.playergetname(players[j])
			if j >= 8 then
				message = message .. "\n.\n.\n.\nFull size of queue: " .. tablelength
				break
			end
		end
		kgp.playersendevent(players[i], "queue", message)
		kgp.playersendevent(players[i], "status", gamestatus)
	end
end

function say(str)
  gamestatus = gamestatus .. "\n\n" .. str
  local tablelength = # players
  for i = 1, tablelength do
    kgp.playersendevent(players[i], "status", gamestatus)
  end
end

function menupost(user, str)
  kgp.playersendevent(user, "display", str)
  display = true
  display_timer = 5000
  oldtick = kgp.scriptgettick()
end

function kgp_arrive(user) 
  --puts the player in the small lobby area (not functioning correctly, the
  --vector is wrong)
  --kgp.playerteleport(user, LOBBY[1], LOBBY[2], LOBBY[3], 1, 90, 1)
  kgp.playerloadmenu(user, "queue.xml")
  kgp.playerloadmenu(user, "gameinfo.xml")
  kgp.playerloadmenu(user, "display.xml")
  if not is_in_table(user, players) then
    say("player " .. kgp.playergetname(user) .. " has joined the game.")
    table.insert(players, user)
  end
  updatemenus()
  say(kgp.playergetname(user) .. " has joined the game.")
  -- update the menus
end

function kgp_depart(user) 
  -- remove user from players table
  remove_element(players, user)
  remove_element(rankings, user)
  updatemenus()
  say(kgp.playergetname(user) .. " has left the game")
  -- update the menus
end

-- take a look at what the menu sends out, act from there.
function kgp_menuevent(user, params)
  if params ~= nil then
    -- add the player to the ready list if they choose ready
    if params[1] == "play" then
      table.insert(ready, user)
    end
    -- if they cancel or choose no, add them to the not ready list
    if params[1] == "noplay" then
      remove_element(ready, user)
      table.insert(notready, user)
    end
    -- if they chose to start the game, run some checks first
    if params[1] == "start" then
      checkstart(user)
    end
    -- handle the onscreen displays
    if params[1] == "display" and display then
      local diff = kgp.scriptgettick() - oldtick
      oldtick = kgp.scriptgettick()
      display_timer = display_timer - diff
      if display_timer <= 0 then
        display = false
        kgp.playersendevent(user, "closedisplay")
      end
    end
  end
end

function teleport_players()
  local spawns = spawn_points[LEVEL_NUMBER]

  -- quit if we don't have enough players
  if table.getn(players) < MIN_PLAYERS then
    menupost(user, "Not enough players to start a game!\nThis is a game for " .. MIN_PLAYERS .. " to " .. MAX_PLAYERS .. " players.")
  else
    asked = 0
    num_players = table.getn(players)
    -- if there are more players available than can play, just ask the max
    -- otherwise ask everyone
    if num_players > MAX_PLAYERS then
      toask = MAX_PLAYERS
    else
      toask = num_players
    end
    for i = 1, toask do
      kgp.playerloadmenu(players[i], "ready.xml")
      timetoask = 10000
    end
    for i = 1, table.getn(players) do
      kgp.playersendevent(players[i], "starting")
    end
    asking = true
    lasttick = kgp.scriptgettick()
  end

  num_players = table.getn(players)
  if num_players > MAX_PLAYERS then 
    num_players = MAX_PLAYERS 
  end

  local x, z, rot, spawn_point
  -- teleport players to the spawn points
  for i=1,num_players do
    spawn_point = spawns[i]
    x = ARENA_X + (BLOCK_SIZE * spawn_point[1])
    z = ARENA_Z + (BLOCK_SIZE * spawn_point[2])
    rot = spawn_point[3]
    kgp.playerteleport(players[i], x, ARENA_Y+16, z, get_rotation(rot))
  end

  -- after players are spawned, the game begins
  gearing_up_timer = 2000
  gearing_up = true
  lasttick = kgp.scriptgettick()
end

function has_player_lost(user)
  if is_in_table(user, players) then
    local x, y, z, rx, ry, rz = kgp.playergetlocation(user)
    return y < ARENA_Y
  else
    -- return true if the player dropped
    return true
  end
end

-- rewrite to be more friendly with menu systems
function kgp_timer(tick)
  -- are we preparing to spawn?
  if ready_to_spawn then
    local diff = tick - lasttick
    lasttick = tick
    timetoask = timetoask - diff
    if timetoask <= 0 then
      local start = asked
      for i = start, toask do
        kgp.playersendevent(players[i], "closeready")
        if is_in_table(players[i], ready) then
          asked = asked + 1
        elseif is_in_table(players[i], notready) then
          asked = asked + 1
        else
          table.insert(notready, players[i])
          asked = asked + 1
        end
      end
      if table.getn(ready) >= MIN_PLAYERS then
        num_players = table.getn(ready)
        asking = false
        for i = 1, table.getn(ready) do
          remove_element(players, ready[i])
          table.insert(players, 1, ready[i])
          kgp.playersendevent(ready[i], "closeready")
          updatemenus()
        end
        build_level(LEVEL_NUMBER)
        teleport_players(LEVEL_NUMBER)
      elseif table.getn(players) <= asked or table.getn(players) < asked + (MIN_PLAYERS - table.getn(ready)) then
        asking = false;
        for i = 1, table.getn(ready) do
          menupost(ready[i], "Not enough people are ready.")
          kgp.playersendevent(ready[i], "closeready")
        end
        for i = 1, table.getn(players) do
          kgp.playersendevent(players[i], "nogame")
        end
      else
        if (MIN_PLAYERS - table.getn(ready)) + asked <= table.getn(players) then
          toask = asked + (MIN_PLAYERS - table.getn(ready))
        else
          toask = table.getn(players)
        end
        timetoask = 10000
      end
    end
  end

  -- are we gearing up?
  if gearing_up then
    local diff = tick - lasttick
    lasttick = tick
    gearing_up_timer = gearing_up_timer - diff
    if gearing_up_timer <= 0 then
      gearing_up = false
      countdown = true
      countdown_timer = 3000
      for i = 1, num_players do
         menupost(players[i], "GET READY.")
      end
    else
      return
    end
  end

  countdown_tick = 0
  if countdown then
    local diff = tick - lasttick
    lasttick = tick
    countdown_timer = countdown_timer - diff
    if countdown_timer < 0 then
      countdown = false
      running = true
      start_game(LEVEL_NUMBER)
      for i = 1, num_players do
         menupost(players[i], "FIGHT!")
      end
    end
  end

  -- has the game begun?
  if running then
    for i = 1, num_players do
      if (not is_in_table(players[i], rankings)) 
        and has_player_lost(players[i]) then
        say(kgp.playergetname(players[i]) .. " just dropped!")
        table.insert(rankings, players[i])
      end
    end
    if table.getn(rankings) >= num_players then
      say("==================================================")
      say("game over! rankings:")
      say("==================================================")
      if rankings[num_players] then
        say("winner: " .. kgp.playergetname(rankings[num_players]))

        if num_players > 1 then
          tally_win(rankings[num_players], num_players-1)
        end
      end
      if rankings[num_players - 1] then
        say("second place: " .. kgp.playergetname(rankings[num_players-1]))
        tally_loss(rankings[num_players-1])
      end
      if rankings[num_players - 2] then
        say("third place: " .. kgp.playergetname(rankings[num_players-2]))
        tally_loss(rankings[num_players-2])
      end
      if rankings[num_players - 3] then
        say("third place: " .. kgp.playergetname(rankings[num_players-3]))
        tally_loss(rankings[num_players-3])
      end
      running = false
      rankings = {}

      for i=1, num_players do
        print_score(players[i])
      end
      destroy_level(LEVEL_NUMBER)
    end
  end
end

------------------------------------------------------------------------------
-- spleef gen code
------------------------------------------------------------------------------
-- a 2D array of blocks
spleef = {{}}
-- global user to send messages to
temp_user = nil
-- set to true when blocks have been placed and exist
is_level = false

function say(str)
  kgp.playertell(temp_user, tostring(str), "DASHBOT", 0)
end

function kgp_start(user)
  kgp.playerloadmenu(user, "queue.xml")
  kgp.playerloadmenu(user, "gameinfo.xml")
  kgp.playerloadmenu(user, "display.xml")
  updatemenus()
end

-- generates a block in the specified coordinate (x and z)
-- gives it the correct texture and attaches the script.
function makespleef(z, x)
  -- calculate position of block
  local posx = ARENA_X + (BLOCK_SIZE * x)
  local posy = ARENA_Y
  local posz = ARENA_Z + (BLOCK_SIZE * z)

  -- generate our spleef block
  local block = kgp.objectgenerate(SPLEEF_BLOCK_GLID, posx, posy, posz, 1, 0, 0)

  -- give it a static block texture for now
  kgp.objectsettexture(block, "filestore9/5368611/6677501/DIF_tiledFloor.jpg", true)

  -- add spleef block to the global spleef blocks table
  spleef[z][x] = block
end

-- attaches spleef scripts to all the objects
function start_game(level_number)
  local width = table.getn(spleef)
  local height = table.getn(spleef[1])
  local level = levels[level_number]
  if not is_level then return end
  -- TODO:
  -- if game_started then return end
  for z = 1, height do
    for x = 1, width do
      if spleef[z][x] and level[z][x] == 2 then
        kgp.objectsetscript(spleef[z][x], SPLEEF_BLOCK_SCRIPT)
      end
    end
  end
  -- TODO:
  -- game_started=true
end

function makewall(z, x)
  -- calculate position of block
  local posx = ARENA_X + (BLOCK_SIZE * x)
  local posz = ARENA_Z + (BLOCK_SIZE * z)

  -- generate our wall block
  local block = kgp.objectgenerate(WALL_GLID, posx, ARENA_Y, posz, 1, 0, 0)
  --kgp.objectsettexture(block, SOLID_BLOCK_TEXTURE)

  -- add wall to the global spleef blocks table
  spleef[z][x] = block
end

function makeempty(z, x) return end

function destroy_level(level_number)
  local width = table.getn(spleef)
  local height = table.getn(spleef[1])
  local level = levels[level_number]
  if not is_level then return end
  for z = 1, height do
    for x = 1, width do
      if spleef[z][x] then
        kgp.objectdelete(spleef[z][x])
      end
    end
  end
  is_level = false
end

build_functions = {}
build_functions[0] = makeempty
build_functions[1] = makewall
build_functions[2] = makespleef

function build_level(level_number)
  local level = levels[level_number]
  local width = table.getn(level)
  local height = table.getn(level[level_number])
  if is_level then destroy_level() end
  spleef = {}
  for z = 1, height do
    spleef[z] = {}
    for x = 1, width do
      build_functions[level[z][x]](z, x)
    end
  end
  is_level = true
  ready_to_spawn = true
  spawn_timer = 5000
  lasttick = kgp.scriptgettick()
  say("starting spawn timer")
end
